next up previous
Next: 5.4 Dynamic Extension Linking Up: 5 Multi-rendering Implementation Previous: 5.2 Reliability Assurances

5.3 PEX Specific Integration Issues

The PEX extension was not written to adhere to these rules; rather, it was adapted from an external body of code,gif so the distinction between code executed by the main thread and that executed in the rendering thread was retrofitted into the imported PEX code.

We did this in a way that does not change the directory structure and file names of the imported code, so that future releases of the original PEX code can be easily integrated into our PEX implementation. For each PEX protocol request, we asked the question: does the code to process this request need access to rendering hardware, or need access to data structures owned by the rendering thread? If the answer is no, then that code was left unchanged; it will be executed only from the main X server thread. Code in the other category was divided into the part to be executed in the X server's main thread and the part to be executed in the rendering thread. Fortunately we were able to fit all of the PEX code into this simple model. Where the code originally was something like this template:

    PEXProcessFoobarRequest(...original args...)
    {
        <check original args>
        <look up resources>
        if (<any errors>)
            return (<some error>);

        <process request>
        return (<result of processing request>);
    }
We changed it to:
    PEXProcessFoobarRequest(...original args...)
    {
        <check original args>
        <look up resources>
        if (<any errors>)
            return (<some error>);

        sgiAsyncExec(ASYNC_PEXProcessFoobarRequest, arg1, ... arg4);
        return (Success);
    }

    ASYNC_PEXProcessFoobarRequest(arg1, ... arg4)
    {
        <process request>
        return (<result of processing request>);
    }
In this scheme the function sgiAsyncExec performs all of the processing necessary to package up the request arguments into a command packet and hand that packet off to the rendering thread, using the push-back mechanism described above. A modification to the PEX dispatch function detects when a pushed-back request has completed, and passes the request completion status back to the client instead of dispatching the request a second time.

This approach works well when the original PEX request processing code looks like the first template above. Where this was not the case, the code was massaged to fit this model. Note that the parameters passed to sgiAsyncExec must be simple variables (but not X resource IDs) or pointers to structures which are guaranteed not to change or disappear until the rendering thread has completed its processing.



next up previous
Next: 5.4 Dynamic Extension Linking Up: 5 Multi-rendering Implementation Previous: 5.2 Reliability Assurances



Mark Kilgard
Sun Jan 7 19:20:04 PST 1996